package com.sftz.modules.minapp.pay.service;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.log.Log;
import org.nutz.log.Logs;

import com.sftz.assets.enums.OrderStatusEnum;
import com.sftz.framework.ioc.CustomIocProvider;
import com.sftz.framework.rersult.MobileResult;
import com.sftz.framework.vendors.minapp.WeappServiceConfig;
import com.sftz.modules.minapp.pay.dto.OrderDto;
import com.sftz.modules.minapp.pay.enums.PayPlatformEnum;
import com.sftz.modules.minapp.pay.enums.PayStatusEnum;
import com.sftz.modules.minapp.pay.enums.WeixinPayChannelEnum;
import com.sftz.modules.minapp.pay.form.OrderPayRecordForm;
import com.sftz.modules.minapp.pay.form.WxMpPayOrderForm;
import com.sftz.modules.minapp.pay.form.WxMpPayResultForm;
import com.sftz.modules.minapp.pay.util.HttpRequest;
import com.sftz.modules.minapp.pay.util.PayCommonUtil;
import com.tencent.common.RandomStringGenerator;
import com.tencent.common.Signature;
import com.tencent.common.XMLParser;
import com.uxuexi.core.common.util.EnumUtil;
import com.uxuexi.core.common.util.Util;

/**
 * 微信小程序支付接口
 */
@IocBean
public class WeappPayViewService {

	private static final Log log = Logs.get();

	@Inject
	private WxMpPayService wxMpPayService;

	@Inject
	private WxMpPayOrderService wxMpPayOrderService;

	private WeappServiceConfig conf = CustomIocProvider.getBean("weappServiceConfig", WeappServiceConfig.class);

	/**
	 * 统一下单
	 * @param form 请求参数
	 */
	public Map<String, Object> unifiedOrder(WxMpPayOrderForm form) {
		try {
			String openid = form.getOpenid();
			if (Util.isEmpty(openid)) {
				return MobileResult.error("请先授权", null);
			}

			if ("undefined".equals(openid)) {
				return MobileResult.error("openid错误:undefined", null);
			}

			form.setOpenid(openid);
			Map<String, Object> result = wxMpPayService.prepay(form);
			String status = (String) result.get(MobileResult.CODE_KEY);
			if (!MobileResult.StatusCode.SUCCESS.key().equals(status)) {
				String message = (String) result.get(MobileResult.MESSAGE_KEY);
				log.info(message);
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			return MobileResult.error("微信支付，统一下单调用异常", null);
		}
	}

	/**
	 * 支付结果异步通知业务处理
	 */
	public void notify(final HttpServletRequest request, final HttpServletResponse response, final int weixinPayWay)
			throws Exception {
		InputStream inStream = request.getInputStream();
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outStream.write(buffer, 0, len);
		}

		//获取微信调用我们notify_url的返回信息
		String responseString = new String(outStream.toByteArray(), "utf-8");
		outStream.close();
		inStream.close();

		PrintWriter out = response.getWriter();
		String resp = "";
		String signKey = "";

		WeixinPayChannelEnum weixinPayChannel = EnumUtil.get(WeixinPayChannelEnum.class, weixinPayWay);
		switch (weixinPayChannel) {
		case APP:
			log.info("APP支付,微信notify签名验证begin.");
			break;
		case MP:
			log.info("公众号支付,微信notify签名验证begin.");
			signKey = conf.getMchKey();
			break;
		case ACNATIVE:
			log.info("公众号扫码支付,微信notify签名验证begin.");
			break;
		default:
			log.info("未知的微信支付类型");
			return;
		}

		boolean verify = Signature.checkIsSignValidFromResponseString(responseString, signKey);
		if (!verify) {
			resp = "签名验证失败";
			out.write(resp);
			out.close();
			return;
		}

		Map<String, Object> map = XMLParser.getMapFromXML(responseString);
		String result_code = map.get("result_code") + "";

		if ("SUCCESS".equalsIgnoreCase(result_code)) {
			//微信支付订单号
			String transaction_id = (String) map.get("transaction_id");

			//支付完成时间
			String time_end = (String) map.get("time_end");

			//订单号
			String out_trade_no = (String) map.get("out_trade_no");
			if (Util.isEmpty(transaction_id) || Util.isEmpty(time_end) || Util.isEmpty(out_trade_no)) {
				resp = PayCommonUtil.getResponseXML("ERROR", "参数错误，微信支付订单号、支付完成时间、订单号均不能为空");
				out.write(resp);
				out.close();
				return;
			}

			OrderDto order = wxMpPayOrderService.fetchOrder(out_trade_no);
			if (!Util.isEmpty(order)) {
				Integer orderStatus = order.getStatus();
				//判断订单状态，避免重复处理
				if (OrderStatusEnum.PAYED.intKey() == orderStatus || OrderStatusEnum.COMPLETE.intKey() == orderStatus) {
					resp = PayCommonUtil.getResponseXML("SUCCESS", "OK");
				} else if (OrderStatusEnum.CANCEL.intKey() == orderStatus) {
					resp = PayCommonUtil.getResponseXML("ERROR", "订单已取消");
				} else if (OrderStatusEnum.WAIT_PAY.intKey() == orderStatus) {
					boolean charge = wxMpPayOrderService.charge(order);
					if (charge) {

						//通知微信服务器处理结果
						resp = PayCommonUtil.getResponseXML("SUCCESS", "OK");

						//添加支付记录
						OrderPayRecordForm rf = new OrderPayRecordForm();
						rf.setOrderId(Integer.valueOf(order.getId() + ""));
						rf.setOrderNo(out_trade_no);
						rf.setPayStatus(PayStatusEnum.SUCCESS.intKey());//支付结果

						rf.setPayPlatform(PayPlatformEnum.WEIXIN.intKey());//支付平台
						rf.setPayWay(weixinPayWay); //支付方式
						rf.setPayTime(time_end);
						rf.setTradeNo(transaction_id);//平台交易号
						wxMpPayOrderService.addPayRecord(rf);

						//订单状态设置为已完成
						order.setStatus(OrderStatusEnum.COMPLETE.intKey());
					} else {
						resp = PayCommonUtil.getResponseXML("ERROR", "订单处理失败");
					}
				} else {
					resp = PayCommonUtil.getResponseXML("ERROR", "订单状态错误");
				}
			}//end of order if
			else {
				resp = PayCommonUtil.getResponseXML("ERROR", "订单不存在");
			}
		} else {
			resp = PayCommonUtil.getResponseXML("ERROR", "ERROR");
		}
		out.write(resp);
		out.close();
	}

	/**
	 * 订单支付结果同步处理
	 */
	@Aop("txDb")
	public Map<String, Object> paySuccess(WxMpPayResultForm form, final int weixinPayWay) throws Exception {
		String signKey = "";
		WeixinPayChannelEnum weixinPayChannel = EnumUtil.get(WeixinPayChannelEnum.class, weixinPayWay);
		switch (weixinPayChannel) {
		case APP:
			log.info("APP支付,同步处理begin.");
			break;
		case MP:
			log.info("公众号支付,同步处理begin.");
			signKey = conf.getMchKey();
			break;
		case ACNATIVE:
			log.info("扫码支付,同步处理begin.");
			break;
		default:
			log.info("未知的微信支付类型");
			return MobileResult.error("未知的微信支付类型", null);
		}

		String orderNo = form.getOrderNo();
		Integer payResult = form.getPayResult();

		//订单号
		if (Util.isEmpty(orderNo)) {
			return MobileResult.error("订单号不能为空", null);
		}

		//微信支付结果
		if (Util.isEmpty(payResult)) {
			return MobileResult.error("支付结果不能为空", null);
		}

		OrderDto order = wxMpPayOrderService.fetchOrder(orderNo);
		if (Util.isEmpty(order)) {
			return MobileResult.error("订单数据错误，订单号:" + orderNo, null);
		}

		//如果支付成功
		if (PayStatusEnum.SUCCESS.intKey() == payResult) {
			Integer orderStatus = order.getStatus();
			//判断订单状态，避免重复处理
			if (OrderStatusEnum.PAYED.intKey() == orderStatus || OrderStatusEnum.COMPLETE.intKey() == orderStatus) {
				return MobileResult.success("订单已处理成功,订单号:" + orderNo, null);
			} else if (OrderStatusEnum.CANCEL.intKey() == orderStatus) {
				return MobileResult.error("订单已取消,订单号:" + orderNo, null);
			} else if (OrderStatusEnum.WAIT_PAY.intKey() == orderStatus) {
				//查询微信订单支付结果
				Map<String, Object> params = new TreeMap<String, Object>();
				params.put("appid", conf.getAppid());
				params.put("mch_id", conf.getMchId());
				params.put("nonce_str", RandomStringGenerator.getRandomStringByLength(32));
				params.put("out_trade_no", order.getOrderNo());

				String sign = Signature.getSign(params, signKey);
				params.put("sign", sign);
				String queryUrl = conf.getQueryOrderUrl();
				String responseXml = HttpRequest.sendPost(queryUrl, params);
				log.info("weixin_query:" + responseXml);
				try {
					Map<String, Object> data = XMLParser.getMapFromXML(responseXml);
					String return_code = (String) data.get("return_code");
					if ("SUCCESS".equals(return_code)) {
						String result_code = data.get("result_code") + "";
						if ("SUCCESS".equalsIgnoreCase(result_code)) {
							String trade_state = data.get("trade_state") + "";
							if ("SUCCESS".equalsIgnoreCase(trade_state)) {
								//如果微信返回支付成功
								boolean charge = wxMpPayOrderService.charge(order);
								if (charge) {
									//添加支付记录
									OrderPayRecordForm rf = new OrderPayRecordForm();
									rf.setOrderId(Integer.valueOf(order.getId() + ""));
									rf.setOrderNo(order.getOrderNo());
									rf.setPayStatus(PayStatusEnum.SUCCESS.intKey());//支付结果

									rf.setPayPlatform(PayPlatformEnum.WEIXIN.intKey());//支付平台
									rf.setPayWay(weixinPayWay); //支付方式

									//微信支付订单号
									String transaction_id = (String) data.get("transaction_id");
									//支付完成时间
									String time_end = (String) data.get("time_end");

									rf.setTradeNo(transaction_id);//平台交易号
									rf.setPayTime(time_end);
									wxMpPayOrderService.addPayRecord(rf);
									return MobileResult.success("订单处理成功", null);
								} else {
									return MobileResult.error("订单处理失败", null);
								}
							} else {
								//如果微信支付不成功
								return MobileResult.error("微信支付还未成功", null);
							}
						} else {
							return MobileResult.error("微信查询接口调用失败", null);
						}
					} else {
						return MobileResult.error((String) data.get("return_msg"), null);
					}
				} catch (Exception e) {
					return MobileResult.error("调用微信接口出错.", null);
				}
			} else {
				return MobileResult.error("订单状态错误,订单号:" + orderNo, null);
			}
		} else {
			return MobileResult.error("订单未支付,订单号:" + orderNo, null);
		}

	}
}
